package com.zl.gmadmin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zl.gmadmin.exception.BaseException;
import com.zl.gmadmin.service.SysDeptService;
import com.zl.gmadmin.utils.LogUtil;
import com.zl.gmadmin.utils.PageUtils;
import com.zl.gmadmin.vo.dept.DeptVo;
import com.zl.gmadmin.entity.SysDept;
import com.zl.gmadmin.mapper.SysDeptMapper;
import com.zl.gmadmin.payload.DeptQueryCriteria;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangliang
 * @version 1.0
 * @date 2021/2/20 17:20
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {


    private final SysDeptMapper sysDeptMapper;

    public SysDeptServiceImpl(SysDeptMapper sysDeptMapper) {
        this.sysDeptMapper = sysDeptMapper;
    }

    @Override
    public List<DeptVo> queryDepts(DeptQueryCriteria criteria) {
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        if (criteria.getName() == "") {
            //不是通过输入查询才需要判断,全查询
            //最开始根节点是没有父节点的需要判断
            if (Objects.isNull(criteria.getPid())) {
                wrapper.isNull("pid");
            } else {
                wrapper.eq("pid", criteria.getPid());
            }
            if (criteria.getEnabled()) {
                //1时候启用当前部门
//                wrapper.eq("enabled", true);
            }
        }

        wrapper.like("name", criteria.getName());
        wrapper.orderBy(criteria.isCondition(), criteria.isAsc(), criteria.getColumn());

        List<SysDept> sysDepts = sysDeptMapper.selectList(wrapper);

        List<DeptVo> DeptVos = new ArrayList<>();

        DeptVos = sysDepts.stream().map(DeptVo::build).collect(Collectors.toList());
//        sysDepts.forEach(sysDept -> {
//            DeptVo deptVo = Builder.of(DeptVo::new)
//                    .with(DeptVo::setId, sysDept.getId())
//                    .with(DeptVo::setPid, sysDept.getPid())
//                    .with(DeptVo::setSubCount, sysDept.getSubCount())
//                    .with(DeptVo::setEnabled, sysDept.getEnabled())
//                    .with(DeptVo::setName, sysDept.getName())
//                    .build();
//            if (sysDept.getSubCount() > 0) {
//                deptVo.setChildren(new ArrayList<>());
//            }
//            DeptVos.add(deptVo);
//        });


        return DeptVos;
    }

    /**
     * 思路:
     * 1.先根据ids查询出当前的部门信息
     * 2.根据当前部门信息pid查询上级部门和同级部门
     * 3.返回数据
     *
     * @param ids
     * @return
     */
    @Transactional(rollbackFor = BaseException.class)
    @Override
    public List<DeptVo> supDepts(List<Long> ids) {
        Set<SysDept> depts = new LinkedHashSet<>();


        for (Long id : ids) {
            SysDept sysDept = sysDeptMapper.selectById(id);
            List<SysDept> sysDepts = supDepts(sysDept, new ArrayList<>());
            depts.addAll(sysDepts);
        }

        LogUtil.debug("部门最后的值是多少:" + JSONUtil.toJsonStr(depts));

        List<SysDept> sysDepts = new ArrayList<>(depts);
        List<DeptVo> deptVos = sysDepts.stream().map(DeptVo::build).collect(Collectors.toList());
        deptVos = buildTree(deptVos);

//       LogUtil.debug("树:"+JSONUtil.toJsonStr(deptVos));

        return deptVos;
    }

    public List<DeptVo> buildTree(List<DeptVo> deptVos) {
        Set<DeptVo> trees = new LinkedHashSet<>();
        Set<DeptVo> deptVoSet = new LinkedHashSet<>();

        List<String> deptNames = deptVos.stream().map(DeptVo::getLabel).collect(Collectors.toList());

        boolean isChild;

        for (DeptVo deptVo : deptVos) {
            isChild = false;
            if (deptVo.getPid() == null) {
                trees.add(deptVo);
            }
            for (DeptVo dv : deptVos) {
                if (ObjectUtil.isNotEmpty(dv.getPid()) && dv.getPid().equals(deptVo.getId())) {
                    isChild = true;
                    if (ObjectUtil.isEmpty(deptVo.getChildren())) {
                        deptVo.setChildren(new ArrayList<>());
                    }
                    deptVo.getChildren().add(dv);
                }
            }
            if (isChild) {
                deptVoSet.add(deptVo);
            } else if (deptVo.getPid() != null && !deptNames.contains(sysDeptMapper.selectById(deptVo.getPid()).getName())) {
                deptVoSet.add(deptVo);
            }
        }
        if (CollectionUtil.isEmpty(trees)) {
            trees = deptVoSet;
        }
        return new ArrayList<>(trees);
    }

    @Override
    @Transactional(rollbackFor = BaseException.class)
    public List<SysDept> supDepts(SysDept sysDept, List<SysDept> sysDepts) {
        // 如果上级为空就是根节点部门，查询所有的根节点部门
        // 有上级节点部门，就递归查询到根节点
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        if (sysDept.getPid() == null) {
            wrapper.isNull("pid");
            sysDepts.addAll(sysDeptMapper.selectList(wrapper));
            return sysDepts;
        }
        //查询同级的
        wrapper.clear();
        wrapper.eq("pid", sysDept.getPid());
        sysDepts.addAll(sysDeptMapper.selectList(wrapper));

//        LogUtil.debug("递归:"+JSONUtil.toJsonStr(sysDepts));

        return supDepts(sysDeptMapper.selectById(sysDept.getPid()), sysDepts);
    }

    @Override
    public Map<String, Object> selectPageVo(DeptQueryCriteria criteria, Page<SysDept> page) {
        QueryWrapper<SysDept> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("pid");
        queryWrapper.orderByAsc("dept_id","dept_sort");

        IPage<SysDept> iPage = sysDeptMapper.selectPageVo(page, queryWrapper);
        List<SysDept> sysDepts = iPage.getRecords();

        List<DeptVo> deptVos = sysDepts.stream().map(DeptVo::build).collect(Collectors.toList());

        return PageUtils.toPage(deptVos, iPage.getTotal());

    }

    @Transactional(rollbackFor = BaseException.class)
    @Override
    public void removeByIdsAndVerification(List<Long> ids) {
//        查询删除存在部门的用户总数
        List<SysDept> sysDeptUsers = sysDeptMapper.deptExistsUsers(ids);
       if (sysDeptUsers.size()>0){
           throw new BaseException(sysDeptUsers.get(0).getName()+"存有用户,总数为: "+sysDeptUsers.get(0).getDeptExistsUsersCount()+",无法删除");
       }

       // 需要减少父节点的子节点数
       ids.forEach(id->{
          SysDept sysDept= sysDeptMapper.selectById(id);
           System.out.println(JSONUtil.toJsonStr(sysDept));
          if (Objects.nonNull(sysDept.getPid())&&!sysDept.getPid().equals("")){
              System.out.println("我有父节点");
              SysDept sysSupDept=sysDeptMapper.selectById(sysDept.getPid());
              sysSupDept.setSubCount(sysSupDept.getSubCount()-1);
              sysDeptMapper.updateById(sysSupDept);
          }
       });
        LogUtil.debug("删除id: "+JSONUtil.toJsonStr(ids));

        sysDeptMapper.deleteBatchIds(ids);
    }

    @Transactional(rollbackFor = BaseException.class)
    @Override
    public Optional<Long> getSameLevelDeptMaxSort(Long pid) {
        return sysDeptMapper.selectSameLevelDeptMaxSort(pid);
    }

    @Transactional(rollbackFor = BaseException.class)
    @Override
    public void saveDept(SysDept sysDept) {
        sysDeptMapper.insert(sysDept);

        //修改父节点的子节点数量
        if (Objects.nonNull(sysDept.getPid())&&!sysDept.getPid().equals("")){
           SysDept sysSupDept=  sysDeptMapper.selectById(sysDept.getPid());
           sysSupDept.setSubCount(sysSupDept.getSubCount()+1);
           sysDeptMapper.updateById(sysSupDept);
        }
    }
    @Transactional(rollbackFor = BaseException.class)
    @Override
    public void updateDept(SysDept sysDept) {
        SysDept sysOldDept= sysDeptMapper.selectById(sysDept.getId());

        if (sysDept.getPid()!=sysOldDept.getPid()) {
            if (Objects.nonNull(sysOldDept.getPid()) && !sysOldDept.getPid().equals("")) {
//            如果原来存在上级部门
                SysDept sysSupDept = sysDeptMapper.selectById(sysOldDept.getPid());
                sysSupDept.setSubCount(sysSupDept.getSubCount() - 1);
                sysDeptMapper.updateById(sysSupDept);
            }

            if (Objects.nonNull(sysDept.getPid()) && !sysDept.getPid().equals("")) {
//            如果现在存在上级部门
                SysDept sysSupDept = sysDeptMapper.selectById(sysDept.getPid());
                sysSupDept.setSubCount(sysSupDept.getSubCount() + 1);
                sysDeptMapper.updateById(sysSupDept);
            }
        }

        // 更新
        sysDeptMapper.updateById(sysDept);
    }
}
